<?php

/**
 * Maikuro CMS
 *
 * LICENSE:
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * The license is bundled with this package in the file LICENSE.txt.
 * You may also obtain a copy of the License at this URL:
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @copyright  Copyright (c) 2010, Jonathan Hedrén
 * @author     Jonathan Hedrén <jonathan.hedren@gmail.com>
 * @license    http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */

require_once 'entity/TemplateEntity.php';

/**
 * 
 */
class TemplateService
{
    const THEMES_DIR    = '/themes/';
    const TEMPLATES_DIR = '/templates/';
    const SNIPPETS_DIR  = '/snippets/';

    /**
     *
     * @var string
     */
    private $basePath;

    /**
     * Constructor. 
     *
     * @return TemplateService
     */
    public function __construct($basePath)
    {
        $this->basePath = $basePath;
        return $this;
    }

    private function doGetTemplate($dir, $name, $theme)
    {
        $filePath = $this->basePath . self::THEMES_DIR . $theme . $dir . $name . '.html';

        if (!is_file($filePath)) {
            return null;
        }

        if (!is_readable($filePath)) {
            throw new Exception('Can not read the file: ' . $filePath);
        }

        $template = $this->create();

        $template->name = $name;
        $template->theme = $theme;
        $template->filePath = $filePath;
        $template->code = file_get_contents($filePath);

        return $template;
    }

    /**
     *
     * @param array $data
     * @return TemplateEntity
     */
    public function create(array $data = null)
    {
        $template = new TemplateEntity();
        if (is_array($data)) {
            foreach ($data as $key => $value) {
                if (!property_exists('TemplateEntity', $key)) {
                    continue;
                }
                $template->$key = $value;
            }
        }
        return $template;
    }

    /**
     *
     * @param TemplateEntity $template
     * @return TemplateService
     */
    public function delete(TemplateEntity $template)
    {
        $filePath = $template->filePath;
        if (!@unlink($template->filePath)) {
            throw new Exception("Can not delete '$filePath' as it is not writeable.");
        }
        return $this;
    }

    /**
     * Returns the snippet entity with the specified name found in the
     * specified theme. Returns null if the snippet file is not found.
     *
     * @param string $name
     * @param string $theme
     * @return TemplateEntity
     */
    public function getSnippet($name, $theme)
    {
        return $this->doGetTemplate(self::SNIPPETS_DIR, $name, $theme);
    }

    /**
     * Returns the template entity with the specified name found in the
     * specified theme. Returns null if the template file is not found.
     *
     * @param string $name
     * @param string $theme
     * @return TemplateEntity
     */
    public function getTemplate($name, $theme)
    {
        return $this->doGetTemplate(self::TEMPLATES_DIR, $name, $theme);
    }

    /**
     * Returns all templates.
     *
     * @return array
     */
    public function getTemplates($theme)
    {
        $templatesPath = $this->basePath . self::THEMES_DIR . $theme . self::TEMPLATES_DIR;
        $directoryIterator = new DirectoryIterator($templatesPath);
        $templates = array();
        foreach ($directoryIterator as $file) {
            if ($file->isDir() || $file->isDot() || !$file->isReadable()) {
                continue;
            }
            $template = $this->create();
            $name = $file->getBasename('.html');
            $filePath = $file->getPathname();

            $template->name = $name;
            $template->theme = $theme;
            $template->filePath = $filePath;
            $template->code = file_get_contents($filePath);
            
            $templates[$name] = $template;
        }
        return $templates;
    }

    /**
     *
     * @param TemplateEntity $template
     * @return TemplateService
     */
    public function save(TemplateEntity $template)
    {
        $filePath = $template->filePath;
        if (!is_writeable($filePath)) {
            throw new Exception("Can not save '$filePath' as it is not writeable.");
        }

        file_put_contents($filePath, $template->code);
        return $this;
    }

    /**
     *
     * @param array $data
     * @return TemplateService
     */
    public function saveFromArray(array $data)
    {
        return $this->save($this->create($data));
    }
}